<?php

declare(strict_types=1);

namespace App\CustHub\Controller;

use App\Common\Constants\StorageModeConstants;
use App\Common\Helpers\QrCode;
use App\CustHub\Annotation\ApiAuth;
use App\CustHub\Annotation\ChOperationLog;
use App\CustHub\Annotation\ChPermission;
use App\CustHub\Annotation\VerifySignature;
use App\CustHub\Dto\ChChannelCodeRecordDto;
use App\CustHub\Service\ChChannelCodeChangeLogService;
use App\CustHub\Service\ChChannelCodeService;
use App\CustHub\Service\ChLockCustomerCodeService;
use App\CustHub\Service\ChRoomCodeService;
use App\Setting\Service\SettingConfigService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Guzzle\ClientFactory;
use Hyperf\HttpMessage\Stream\SwooleFileStream;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;

#[Controller(prefix: "ch/attract/channelCode"), ApiAuth, VerifySignature]
class ChChannelCodeController extends BaseController
{
    #[Inject]
    protected ChChannelCodeService $service;

    #[Inject]
    protected ChRoomCodeService $chRoomCodeService;

    #[Inject]
    protected ChLockCustomerCodeService $lockService;

    #[Inject]
    protected ChChannelCodeChangeLogService $changeLogService;

    public array $noNeedLogin = ['downloadCode','exportReport', 'getQrCode', 'lockQrCodeOrLink','codeInfo','getLiveCodeUrl','QrcodeDisplay'];
    public array $noNeedVerifySign = ['downloadCode','exportReport', 'getQrCode', 'lockQrCodeOrLink','codeInfo','getLiveCodeUrl','QrcodeDisplay'];


    #[GetMapping('downloadCode')]
    public function downloadCode(): ResponseInterface
    {
        $code = $this->service->mapper->findById($this->request->input('id'));
        $fileUrl=$code->code;
        $client = container()->get(ClientFactory::class)->create();
        $response = $client->get($fileUrl);

        $fileContent = $response->getBody()->getContents();
        $fileName=basename($fileUrl);

        // 获取文件类型
        $contentType = $response->getHeaderLine('Content-Type') ?: 'application/octet-stream';

        return $this->response
            ->withHeader('Content-Type', $contentType)
            ->withHeader('Content-Disposition', 'attachment; filename=' . $fileName)
            ->withHeader('Content-Length', (string) strlen($fileContent))
            ->withBody(new SwooleStream($fileContent));
    }

    /**
     * 获取活码列表
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     */
    #[PostMapping('list'), ChPermission("ch:attract:channelCode:list")]
    public function getChannelCodeList(): ResponseInterface
    {
        return $this->success($this->service->getChannelCodeList($this->request->all()));
    }

    /**
     * 新增活码
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     */
    #[PostMapping('save'), ChPermission("ch:attract:channelCode:add"), ChOperationLog]
    public function saveChannelCode(): ResponseInterface
    {
        return $this->success(['id' => $this->service->saveChannelCode($this->request->all())]);
    }

    /**
     * 更新活码
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     */
    #[PutMapping('update'), ChPermission("ch:attract:channelCode:update")]
    public function updateChannelCode(): ResponseInterface
    {
        return $this->service->updateChannelCode($this->request->all()) ? $this->success() : $this->error();
    }

    /**
     * 删除活码
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     */
    #[DeleteMapping('delete'), ChPermission("ch:attract:channelCode:update"), ChOperationLog]
    public function deleteChannelCode(): ResponseInterface
    {
        return $this->service->deleteChannelCode($this->request->all()) ? $this->success() : $this->error();
    }

    /**
     * 获取活码详情
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     */
    #[PostMapping('detail'), ChPermission("ch:attract:channelCode:detail")]
    public function getChannelCodeDetail(): ResponseInterface
    {
        return $this->success($this->service->getCodeDetail($this->request->all()));
    }

    /**
     * 获取活码数据
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     */
    #[PostMapping('data'), ChPermission("ch:attract:channelCode:data")]
    public function getChannelCodeData(): ResponseInterface
    {
        return $this->success($this->service->getChannelCodeData($this->request->all()));
    }

    /**
     * 获取活码分日数据
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     */
    #[PostMapping('dailyData'), ChPermission("ch:attract:channelCode:dailyData")]
    public function getChannelCodeDailyData(): ResponseInterface
    {
        return $this->success($this->service->getChannelCodeDailyData($this->request->all()));
    }

    /**
     * 获取活码机器人数据
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     */
    #[PostMapping('robotData'), ChPermission("ch:attract:channelCode:robotData")]
    public function getChannelCodeRobotData(): ResponseInterface
    {
        return $this->success($this->service->getChannelCodeRobotData($this->request->all()));
    }

    /**
     * 获取活码修改记录
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     */
    #[PostMapping('changeLog'), ChPermission("ch:attract:channelCode:changeLog")]
    public function getChannelCodeChangeLog(): ResponseInterface
    {
        return $this->success($this->changeLogService->getChannelCodeChangeLog($this->request->all()));
    }

    /**
     * 获取活码数据报表
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     */
    #[PostMapping('codeReport')]
    public function getChannelCodeReport()
    {
        $params = $this->request->all();
        return $this->success($this->service->getChannelCodeReport($params));
    }

    /**
     * 获取活码数据报表详情
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     */
    #[PostMapping('codeReportDetail')]
    public function getChannelCodeReportDetail()
    {
        $params = $this->request->all();
        return $this->success($this->service->getChannelCodeReportDetail($params));
    }

    /**
     * 导出数据报表
     * @return ResponseInterface
     */
    #[GetMapping('exportReport'), ChPermission('ch:attract:channelCode:exportReport'), ChOperationLog]
    public function exportChannelCodeReport()
    {
        return $this->service->exportChannelCodeReport($this->request->all(), ChChannelCodeRecordDto::class);
    }

    /**
     * 获取机器人二维码
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    #[GetMapping('getQrCode')]
    public function getQrCode(): ResponseInterface
    {
        return $this->success(['qr_code' => $this->service->getQrCode($this->request->input('id'))]);
    }

    /**
     * 锁客码列表
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    #[PostMapping('lockList'), ChPermission("ch:attract:channelCode:lockList")]
    public function getLockCustomerCodeList(): ResponseInterface
    {
        return $this->success($this->lockService->getLockCustomerCodeList($this->request->all()));
    }

    /**
     * 新增锁客码
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    #[PostMapping('lockSave'), ChPermission("ch:attract:channelCode:lockSave"), ChOperationLog]
    public function saveLockCustomerCode(): ResponseInterface
    {
        return $this->success(['id' => $this->lockService->saveLockCustomerCode($this->request->all())]);
    }

    /**
     * 更新锁客码
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    #[PutMapping('lockUpdate'), ChPermission("ch:attract:channelCode:lockUpdate"), ChOperationLog]
    public function updateLockCustomerCode(): ResponseInterface
    {
        return $this->lockService->updateLockCustomerCode($this->request->all()) ? $this->success() : $this->error();
    }

    /**
     * 删除锁客码
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    #[DeleteMapping('lockDelete'), ChPermission("ch:attract:channelCode:lockDelete"), ChOperationLog]
    public function deleteLockCustomerCode()
    {
        return $this->lockService->deleteLockCustomerCode($this->request->all()) ? $this->success() : $this->error();
    }

    /**
     * 获取锁客码详情
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    #[PostMapping('lockDetail'), ChPermission("ch:attract:channelCode:lockDetail")]
    public function getLockCustomerCodeDetail(): ResponseInterface
    {
        return $this->success($this->lockService->getLockCustomerCodeDetail($this->request->all()));
    }

    /**
     * 扫描锁客码
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    #[GetMapping('lockQrCodeOrLink')]
    public function getLockQrCode(): ResponseInterface
    {
        return $this->success($this->lockService->handleLockCustomer($this->request->all()));
    }

    /**
     * 活码样式
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    #[GetMapping('QrcodeDisplay')]
    public function QrcodeDisplay(): ResponseInterface
    {
        $display = container()->get(Qrcode::class)->generationRandomQrCodeWithLogo(['logo' => $this->request->input('qr_code_cfg')], StorageModeConstants::LOCAL);
        return $this->success($display);
    }


    #[GetMapping('codeInfo')]
    public function codeInfo()
    {
        $type=$this->request->input('type');
        $data = match ((int)$type) {
            1 => $this->service->codeInfo($this->request->all()),
            2 => $this->chRoomCodeService->getRoomQrcode($this->request->all()),
            default => []
        };
        return $this->success($data);
    }

    #[GetMapping('getLiveCodeUrl')]
    public function getLiveCodeUrl()
    {
        $chain_code=$this->request->input('chain_code');
        $type=$this->request->input('type');
        $systemConfig = container()->get(SettingConfigService::class);
        $url = $systemConfig->getConfigByKey('code_page_url')['value']."/".$chain_code."?type=".$type."&is_redirect=0";
        return $this->success(['url'=>$url]);
    }

}